package com.advert.model.advert;

import com.advert.model.OwnedEntityBase;
import com.advert.model.security.Status;
import com.advert.model.support.AdvertType;
import com.advert.model.support.CurrencyEntity;
import com.advert.model.support.ProductType;
import com.advert.model.support.RegionEntity;
import com.advert.model.vehicle.VehicleEntity;

import javax.persistence.*;
import static javax.persistence.CascadeType.*;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Entity
@Table(name = "advert")
@NamedQueries({
    @NamedQuery(name = "AdvertEntity.getByType", query = "select a from AdvertEntity a where a.type = :type and a.status = :status order by advertDate desc"),
    @NamedQuery(name = "AdvertEntity.getByTypeAndProductType", query = "select a from AdvertEntity a where a.type = :type and a.productType = :productType and a.status = :status order by advertDate desc"),
    @NamedQuery(name = "AdvertEntity.getByTypeAndProductTypeAndVehicleType", query = "select a from AdvertEntity a where a.type = :type and a.productType = :productType and a.vehicle.typeCode = :vehicleType and a.status = :status order by advertDate desc"),
    @NamedQuery(name = "AdvertEntity.getByTypeAndProductTypeAndVehicleCategory", query = "select a from AdvertEntity a where a.type = :type and a.productType = :productType and a.vehicle.categoryCode = :vehicleCategory and a.status = :status order by advertDate desc"),
    @NamedQuery(name = "AdvertEntity.getByOwnerId", query = "select a from AdvertEntity a where a.ownerId = :ownerId order by advertDate desc"),
    @NamedQuery(name = "AdvertEntity.getByStatus", query = "select a from AdvertEntity a where a.status = :status order by advertDate desc"),
    @NamedQuery(name = "AdvertEntity.getCountByType", query = "select count(a) from AdvertEntity a where a.type = :type and a.status = :status order by advertDate asc"),
    @NamedQuery(name = "AdvertEntity.getCountByTypeAndProductType", query = "select count(a) from AdvertEntity a where a.type = :type and a.productType = :productType and a.status = :status"),
    @NamedQuery(name = "AdvertEntity.getCountByTypeAndProductTypeAndVehicleType", query = "select count(a) from AdvertEntity a where a.type = :type and a.productType = :productType and a.vehicle.typeCode = :vehicleType and a.status = :status"),
    @NamedQuery(name = "AdvertEntity.getCountByTypeAndProductTypeAndVehicleCategory", query = "select count(a) from AdvertEntity a where a.type = :type and a.productType = :productType and a.vehicle.categoryCode = :vehicleCategory and a.status = :status"),
    @NamedQuery(name = "AdvertEntity.getCountByOwnerId", query = "select count(a) from AdvertEntity a where a.ownerId = :ownerId"),
    @NamedQuery(name = "AdvertEntity.getCountByStatus", query = "select count(a) from AdvertEntity a where a.status = :status order by advertDate asc")     
})
public class AdvertEntity extends OwnedEntityBase {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "type")
    @Enumerated(EnumType.STRING)
    private AdvertType type;

    @Column(name = "status")
    @Enumerated(EnumType.STRING)
    private Status status;

    @Column(name = "product_type")
    @Enumerated(EnumType.STRING)
    private ProductType productType = ProductType.V; // TODO: change this

    @Column(name = "vehicle_id", insertable = false, updatable = false)
    private Integer vehicleId;

    @Column(name = "currency_cd")
    private String currencyCd;

    @Column(name = "region_cd")
    private String regionCd;

    @Column(name = "price")
    private BigDecimal price;

    @Column(name = "description")
    private String description;

    @Column(name = "contact_info")
    private String contactInfo;

    @Column(name = "reject_reason")
    private String rejectReason;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "advert_date")
    private Date advertDate;

    @OneToOne(cascade = {PERSIST, REMOVE}, fetch = FetchType.EAGER)
    @JoinColumn(name = "vehicle_id", referencedColumnName = "id")
    private VehicleEntity vehicle;

    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "currency_cd", referencedColumnName = "code", insertable = false, updatable = false)
    private CurrencyEntity currency;

    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "region_cd", referencedColumnName = "code", insertable = false, updatable = false)
    private RegionEntity region;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "advert")
    private List<ImageEntity> images;

    @OneToMany(cascade = PERSIST, fetch = FetchType.LAZY, mappedBy = "advert")
    private List<ImageLobsEntity> imageLobs;    


    public Integer getId() {
        return id;
    }

    public AdvertType getType() {
        return type;
    }

    public void setType(AdvertType type) {
        this.type = type;
    }

    public String getCurrencyCd() {
        return currencyCd;
    }

    public void setCurrencyCd(String currencyCd) {
        this.currencyCd = currencyCd;
    }

    public String getRegionCd() {
        return regionCd;
    }

    public void setRegionCd(String regionCd) {
        this.regionCd = regionCd;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public VehicleEntity getVehicle() {
        return vehicle;
    }

    public void setVehicle(VehicleEntity vehicle) {
        this.vehicle = vehicle;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getContactInfo() {
        return contactInfo;
    }

    public void setContactInfo(String contactInfo) {
        this.contactInfo = contactInfo;
    }

    public CurrencyEntity getCurrency() {
        return currency;
    }

    public RegionEntity getRegion() {
        return region;
    }

    public List<ImageEntity> getImages() {
        return images;
    }

    public void setImageLobs(List<ImageLobsEntity> images) {
        for (ImageLobsEntity image : images) {
            image.setAdvert(this);
        }
        this.imageLobs = images;
    }

    public Date getAdvertDate() {
        return advertDate;
    }

    public void setAdvertDate(Date advertDate) {
        this.advertDate = advertDate;
    }

    public ProductType getProductType() {
        return productType;
    }

    public void setProductType(ProductType productType) {
        this.productType = productType;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public String getRejectReason() {
        return rejectReason;
    }

    public void setRejectReason(String rejectReason) {
        this.rejectReason = rejectReason;
    }
}
